import CRS from "./CRS";
import ProjectMercator from "../geo/Projection.Mercator";
import { toTransformation } from "../geometry/Transformation";

import { toPoint } from "../geometry/Point";

export default class CRSEPSG3857 extends CRS {
  code = "EPSG:3857";
  projection = new ProjectMercator();
  transformation;
  constructor() {
    super();
    this.setTransformation();
  }
  setTransformation() {
    const scale = 0.5 / (Math.PI * super.getEARTHRAD());
    this.transformation = toTransformation(scale, 0.5, -scale, 0.5);
  }
  // 经纬度转点
  lngLatToPoint(lnglat, zoom) {
    // 把经纬度转web墨卡托投影
    const projectedPoint = this.projection.project(lnglat),
      scale = this.scale(zoom);
    // 墨卡托投影的原点在非洲旁边，把他偏移到瓦片原点
    return this.transformation._transform(projectedPoint, scale);
  }

  // 该方法已废弃，这个的好处是很直观的看出坐标间的转换， 和 lngLatToPoint 结果一致
  getPxFromLngLat = (lnglat, z) => {
    const mer = this.projection.project(lnglat);
    let _x = mer.x;
    let _y = mer.y;
    // 转成世界平面图的坐标
    _x += super.getEARTHRAD() / 2;
    _y = super.getEARTHRAD() / 2 - _y;
    let resolution = super.getResolution(z); // 该层级的分辨率
    return toPoint(_x / resolution, _y / resolution);
  };

  // 点转经纬度
  pointToLatLng(point, zoom) {
    const scale = this.scale(zoom),
      untransformedPoint = this.transformation.untransform(point, scale);

    return this.projection.unproject(untransformedPoint);
  }
    bbox(x, y, z) {
    const point = toPoint(x, y);
    const size = toPoint(256, 256);

    const startPoint = point.scaleBy(size);
    const endPoint = startPoint.add(size);
    const leftTop = this.pointToLatLng(startPoint, z)
    const  rightBottom= this.pointToLatLng(endPoint, z)
    return [
      leftTop.lng,
      rightBottom.lat,
      rightBottom.lng,
      leftTop.lat,
    ].toString();
  }


}

export const EPSG3857 = () => {
  return new CRSEPSG3857();
};
